package bccsp

/**
bccsp 区块链基础密码学使用基础模块
CSP 密码学
@date:2022.2.22
@author:lwj
*/
import (
	"crypto"
	"hash"
)

//所有带opts的 基本里面带参数，或者像工厂一样会改变函数、方法的效果

// Key表 示加密密钥key interface
type Key interface {

	// 如果操作允许的情况下,该方法时将把key转变为byte[]
	Bytes() ([]byte, error)

	// 返回秘钥的唯一标志符 ski
	SKI() []byte

	// 返回是否是对称秘钥
	// 如果是的就返回true
	// 否则返回false
	Symmetric() bool

	// 返回是否是私钥
	// 如果是私钥就返回true
	// 否则返回false
	// 如果是对称钥,默认返回true
	Private() bool

	// 如果是私钥,返回对应的公钥
	// 如果是公钥,直接返回秘钥
	// 如果是
	PublicKey() (Key, error)
}

// 秘钥生成操作 interface
type KeyGenOpts interface {

	// 返回秘钥生成算法名称
	Algorithm() string

	// 该算法产生的key是否是暂时的
	// 如果是暂时的就返回true
	// 否则返回false
	Ephemeral() bool
}

// 是key派生算法的interface
type KeyDerivOpts interface {

	// 派生算法名称
	Algorithm() string

	// 该算法派生的key是否是暂时的
	// 如果是暂时的就返回true
	// 否则返回false
	Ephemeral() bool
}

// KeyImportOpts包含使用CSP导入密钥的原材料的选项
// 使用原始材料生成key interface
type KeyImportOpts interface {

	// import算法名称
	Algorithm() string

	//如果生成的密钥必须是短暂的，则返回true，
	//错误。
	Ephemeral() bool
}

// hash操作的interface
type HashOpts interface {

	// hash算法名称
	Algorithm() string
}

// 签名操作interface
type SignerOpts interface {
	crypto.SignerOpts
}

// 加密操作 interface
type EncrypterOpts interface{}

// 解密操作 interface
type DecrypterOpts interface{}

// BCCSP是提供的区块链加密服务提供interface
// 密码标准和算法的实现。
// 最基础的生成服务
type BCCSP interface {

	// KeyGen使用opts生成密钥。
	KeyGen(opts KeyGenOpts) (k Key, err error)

	// 使用opts操作从key 派生一个key秘钥
	KeyDeriv(k Key, opts KeyDerivOpts) (dk Key, err error)

	// 使用opts操作从raw产生一个key秘钥
	// opts参数应该适合所使用的raw类型
	KeyImport(raw interface{}, opts KeyImportOpts) (k Key, err error)

	// 从ski标识符返回其所对应的key秘钥
	GetKey(ski []byte) (k Key, err error)

	// hash一个数值,如果操作值为空,则默认hash函数将会使用
	Hash(msg []byte, opts HashOpts) (hash []byte, err error)

	// GetHash返回hash的实例。使用选项的散列选项。
	// 如果opts为nil，则返回默认的哈希函数。
	GetHash(opts HashOpts) (h hash.Hash, err error)

	// 使用秘钥k对digest进行签名摘要,使用算法为opts
	// opts参数应该适合所使用的算法。
	// 注意，当需要一个较大消息的哈希签名时，调用者负责哈希较大消息,再将这个hash值使用这个方法进行签名。
	Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error)

	// Verify根据密钥k和摘要验证签名
	// opts参数应该适合所使用的算法。
	Verify(k Key, signature, digest []byte, opts SignerOpts) (valid bool, err error)

	// Encrypt使用密钥k加密明文。
	// opts参数应该适合所使用的算法。
	Encrypt(k Key, plaintext []byte, opts EncrypterOpts) (ciphertext []byte, err error)

	// Decrypt使用密钥k解密密文。
	// opts参数应该适合所使用的算法。
	Decrypt(k Key, ciphertext []byte, opts DecrypterOpts) (plaintext []byte, err error)
}
